package com.atguigu.gulimall.product.service.impl;

import com.atguigu.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.atguigu.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.atguigu.gulimall.product.entity.AttrEntity;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.AttrAttrgroupRelationService;
import com.atguigu.gulimall.product.service.AttrService;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.AttrAttrgroupRelationVo;
import com.atguigu.gulimall.product.vo.AttrGroupWithAttrsVo;
import com.atguigu.gulimall.product.vo.sku.SkuItemVo;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.AttrGroupDao;
import com.atguigu.gulimall.product.entity.AttrGroupEntity;
import com.atguigu.gulimall.product.service.AttrGroupService;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    AttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    @Autowired
    AttrService attrService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catId) {
        String key = params.getOrDefault("key", "").toString();
        QueryWrapper<AttrGroupEntity> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and((obj) -> {
                obj.eq("attr_group_id", key).or().like("attr_group_name", key);
            });
        }
        if (catId != 0) {
            queryWrapper.eq("catelog_id", catId);
        }
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    public Collection<AttrEntity> queryAttrRelation(Long attrGroupId) {
        // 查询关联 类别id
        List<Long> attrIds = attrAttrgroupRelationService.list(
                        new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId))
                .stream()
//                .mapToLong(AttrAttrgroupRelationEntity::getAttrId)
//                .filter(Objects::nonNull)
//                .boxed()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());
        if (!attrIds.isEmpty()) {
            return attrService.listByIds(attrIds);
        }
        return null;
    }

    @Override
    public void deleteRelation(List<AttrAttrgroupRelationVo> attrAttrgroupRelationVos) {
        List<AttrAttrgroupRelationEntity> entityList = attrAttrgroupRelationVos.stream().map(t -> {
            AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(t, entity);
            return entity;
        }).collect(Collectors.toList());
        attrAttrgroupRelationDao.deleteBatchRelations(entityList);
    }

    @Override
    public PageUtils queryNoAttrRelation(Long attrGroupId, Map<String, Object> params) {
        // 根据属性分组id，查询当前分组未关联的属性信息
        // 1. 封装分页查询条件
        String key = params.getOrDefault("key", "").toString();
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and((obj) -> {
                obj.eq("attr_id", key).or().like("attr_name", key);
            });
        }

        // 2. 获取当前分组id所属的类别id
        AttrGroupEntity attrGroupEntity = this.baseMapper.selectById(attrGroupId);
        Long catelogId = attrGroupEntity.getCatelogId();

        // 3. 当前分组只能关联别的分组没有引用的属性信息

        // 3.1 当前类别id，下的其他分组id
        List<Long> groupIds = this.baseMapper
                .selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId))
                .stream().map(AttrGroupEntity::getAttrGroupId)
                .collect(Collectors.toList());

        // 3.2 这些分组id所关联的属性信息
        List<Long> attrIds = attrAttrgroupRelationDao
                .selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", groupIds))
                .stream().map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());

        // 3.3 从当前分类的所有属性中移除已经关联的属性信息
        queryWrapper.eq("catelog_id", catelogId);
        queryWrapper.notIn("attr_id", attrIds);


        IPage<AttrEntity> page = attrService.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    public List<AttrGroupWithAttrsVo> getAttrGroupWithAttrs(Long catelogId) {
        List<AttrGroupWithAttrsVo> entities = this.baseMapper.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId))
                .stream().map(item -> {
                    AttrGroupWithAttrsVo attrGroupWithAttrsVo = new AttrGroupWithAttrsVo();
                    BeanUtils.copyProperties(item, attrGroupWithAttrsVo);
                    Collection<AttrEntity> attrEntities = this.queryAttrRelation(item.getAttrGroupId());
                    attrGroupWithAttrsVo.setAttrs(attrEntities);
                    return attrGroupWithAttrsVo;
                }).collect(Collectors.toList());
        return entities;
    }

    @Override
    public List<SkuItemVo.SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuIdAndCatalogId(Long spuId, Long catalogId) {
        return baseMapper.getAttrGroupWithAttrsBySpuIdAndCatalogId(spuId, catalogId);
    }
}